<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原型对象</title>
</head>
<body>
    
</body>
</html>
<script>
    /*
        原型prototype

            我们所创建的每一个函数，解析器都会向函数中添加一个属性prototype
                这个属性对应着一个对象，这个对象就是我们所谓的原型对象
            如果函数作为普通的函数调用，prototype没有任何作用
            当函数以构造函数的形式调用时，他所创建的对象中都会有一个隐含的属性，
                指向该构造函数的原型对象，我们可以通过__proto__来访问该属性

            原型对象就相当于公共的区域，所有同一个类的实例都可以访问到原型对象
                我们可以将对象中共有的内容，同一设置到原型对象中。

        当我们访问对象的一个属性或方法时，会先在对象自身中寻找，如果有则直接使用，
            如果没有，则到原型对象中寻找

        以后创建构造函数时，可以：
            将这些对象共有的属性和方法，统一添加到构造函数的原型对象中，
            这样不用分别为每一个对象添加，也不会影响到全局作用域，
            可以使构造函数的每个对象都具有这些属性和方法
    */
    
    function MyClass(){

    }

    // 向 MyClass 中添加一个属性 a
    MyClass.prototype.a = 123;

    var mc = new MyClass();
    var mc2 = new MyClass();
    mc2.a = "我是mc2中的a";
    console.log(MyClass.prototype);
    console.log(MyClass.prototype.a);
    console.log(mc.a);
    console.log(mc2.a);
    console.log(mc.__proto__ == mc2.__proto__);


    /*
        利用 原型对象 对 构造函数修复
    */
    function Preson(name,age){
        
        this.name=name;
        this.age=age;
    }
    // 向 Preson 原型中添加 sayName方法
    //  所有Preson类的对象都能访问，且不污染全局作用域命名，减少资源浪费
    Preson.prototype.sayName=function(){
        alert("大家好，I'm : "+this.name);
    }

    //  实例化Preson
    var pre = new Preson("孙悟空",18);
    
    console.log(pre.__proto__);
    console.log(Preson.prototype);
    // 调用原型对象的 saName 方法
    pre.sayName();
</script>